﻿' This file explains how you should use the Compiler tool to create a new function.

' 1. Add a reference to the Enhancements.Basic assembly.
' 2. Create a class derived from the Enhancements.Basic.Expressions.Functions.Function class.
' 3. Follow the comments below.
' 4. When the function is done, to make it available to a Compiler instance,
'    state it in the Compiler constructor.

Imports Enhancements.Basic.Expressions
Imports Ope = Enhancements.Basic.Expressions.Operators
Imports Val = Enhancements.Basic.Expressions.Values

Public Class NewFunction
    Inherits Functions.Function

    'This function verifies that a value is in a specified range, returning True or False:
    'Signatures made available:
    '   Value as Integer, Minimum as Integer, Maximum as Integer, Return as Boolean
    '   Value as Decimal, Minimum as Decimal, Maximum as Decimal, Return as Boolean

    'Holding variables for the signatures made available. They will be needed when the solving process 
    'is invoked by the compiler tool
    Private Shared __SignatureIntegerIntegerInteger As Functions.FunctionSignature = Nothing
    Private Shared __SignatureDecimalDecimalDecimal As Functions.FunctionSignature = Nothing

    'Create the signatures
    Shared Sub New()

        __SignatureIntegerIntegerInteger = New Functions.FunctionSignature(
            New Functions.FunctionSignatureParameter() { _
                New Functions.FunctionSignatureParameter("Value", GetType(Val.Integer)), _
                New Functions.FunctionSignatureParameter("Minimum", GetType(Val.Integer)), _
                New Functions.FunctionSignatureParameter("Maximum", GetType(Val.Integer)) _
            }, _
            New Functions.FunctionSignatureResult(GetType(Val.Boolean)))

        __SignatureDecimalDecimalDecimal = New Functions.FunctionSignature(
            New Functions.FunctionSignatureParameter() { _
                New Functions.FunctionSignatureParameter("Value", GetType(Val.Decimal)), _
                New Functions.FunctionSignatureParameter("Minimum", GetType(Val.Decimal)), _
                New Functions.FunctionSignatureParameter("Maximum", GetType(Val.Decimal)) _
            }, _
            New Functions.FunctionSignatureResult(GetType(Val.Boolean)))

    End Sub

    'When instantiated, a function MUST call its base constructor to state her nature
    Public Sub New()
        MyBase.New( _
            "IsInRange", _
            New Functions.FunctionSignature() {__SignatureIntegerIntegerInteger, __SignatureDecimalDecimalDecimal}, _
            Nothing)
    End Sub

    'This function is called when the tool needs to solve an expression part
    'You get the signature it wishes you to use and the values
    'You return the output of the calculation, with the exact type that signature states
    Public Overrides Function Solve(ByVal _signature As Functions.FunctionSignature, ByVal _parametersValues() As Object) As Object
        Dim _returnValue As Object = Nothing
        If _signature.Equals(__SignatureIntegerIntegerInteger) Then
            _returnValue = __SolveSignatureIntegerIntegerInteger(_parametersValues(0), _parametersValues(1), _parametersValues(2))
        Else
            If _signature.Equals(__SignatureDecimalDecimalDecimal) Then
                _returnValue = __SolveSignatureDecimalDecimalDecimal(_parametersValues(0), _parametersValues(1), _parametersValues(2))
            End If
        End If

        Return _returnValue
    End Function

    Private Function __SolveSignatureIntegerIntegerInteger(ByVal _value As Object, ByVal _minimum As Object, ByVal _maximum As Object) As System.Boolean
        Dim _valueCasted As System.Int64 = CType(_value, System.Int64)
        Dim _minimumCasted As System.Int64 = CType(_minimum, System.Int64)
        Dim _maximumCasted As System.Int64 = CType(_maximum, System.Int64)
        Dim _returnValue As System.Boolean = _valueCasted >= _minimumCasted And _valueCasted <= _maximumCasted

        Return _returnValue
    End Function

    Private Function __SolveSignatureDecimalDecimalDecimal(ByVal _value As Object, ByVal _minimum As Object, ByVal _maximum As Object) As System.Boolean
        Dim _valueCasted As System.Decimal = CType(_value, System.Decimal)
        Dim _minimumCasted As System.Decimal = CType(_minimum, System.Decimal)
        Dim _maximumCasted As System.Decimal = CType(_maximum, System.Decimal)
        Dim _returnValue As System.Boolean = _valueCasted >= _minimumCasted And _valueCasted <= _maximumCasted

        Return _returnValue
    End Function

End Class
